package org.university.util;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTException;
import cn.hutool.jwt.JWTUtil;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.university.config.JwtConfig;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 修正后的JWT工具类，使用Hutool正确的验证方式
 */
@Component
public class JwtUtils {

    private final static Logger LOGGER = LoggerFactory.getLogger(JwtUtils.class);

    @Resource
    private JwtConfig jwtConfig;

    /**
     * 生成Token
     * @param userId 用户ID
     * @param role 用户角色
     * @return Token字符串
     */
    public String generateToken(Long userId, String role) {
        // 计算过期时间（当前时间戳 + 过期秒数，单位：秒）
        long expireTime = System.currentTimeMillis() / 1000 + jwtConfig.getExpireSeconds();

        // 设置Token载荷
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtConfig.USER_ID_CLAIM, userId);
        claims.put(JwtConfig.ROLE_CLAIM, role);
        claims.put("exp", expireTime); // 过期时间（Hutool会自动校验）

        // 生成Token
        return JWT.create()
                .addPayloads(claims)
                .setKey(jwtConfig.getSecretKey().getBytes(StandardCharsets.UTF_8))
                .sign();
    }

    /**
     * 验证Token并返回JWT对象
     *
     * @param token Token字符串
     * @return 验证通过的JWT对象
     * @throws JWTException 验证失败时抛出异常
     */
    public boolean verifyToken(String token) throws JWTException {
        if (token == null || token.trim().isEmpty()) {
            throw new JWTException("Token不能为空");
        }

        try {
            return JWTUtil.verify(token, PasswordUtil.getSecretKey().getBytes());
        } catch (JWTException e) {
            throw new JWTException("Token验证失败: " + e.getMessage());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 从Token中获取用户ID
     */
    public String getUserId(JWT jwt) {
        // 安全获取 payload 值, userId字段的值不存在
        Object userIdObj = jwt.getPayload("uid");

        if (userIdObj == null) {
            LOGGER.error("JWT uid字段不存在");
            return null;
        }

        return userIdObj.toString();
    }

    /**
     * 从请求头中提取Token
     */
    public String extractToken(String authHeader) {
        if (authHeader == null || !authHeader.startsWith(JwtConfig.TOKEN_PREFIX)) {
            return null;
        }
        return authHeader.substring(JwtConfig.TOKEN_PREFIX.length()).trim();
    }
}
